package com.qiyu.tech.gateway.auth;

import com.alibaba.fastjson.JSON;
import com.qiyu.core.cache.redis.client.RedisService;
import com.qiyu.tech.gateway.dao.mapper.BlackListMapper;
import com.qiyu.tech.gateway.dao.po.BlackListPO;
import com.qiyu.tech.gateway.event.task.InsertNodeTask;
import com.qiyu.tech.gateway.service.AbstractZookeeperClient;
import com.qiyu.tech.gateway.service.impl.CuratorZookeeperClient;
import com.sun.org.apache.xml.internal.security.Init;
import org.apache.curator.framework.CuratorFramework;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author linhao
 * @Date created in 8:50 上午 2021/3/17
 */
@Service
@Scope(value = "singleton")
public class BlackListCacheManager implements IBlackListCacheManager, InitializingBean {

    @Resource
    private BlackListMapper blackListMapper;
    //    @Resource
//    private RedisService redisService;
    @Resource
    private IBlackListCache iBlackListCache;

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Value("${zookeeper.address}")
    private String zookeeperAddress;

    @Value("${zookeeper.port}")
    private Integer zkPort;

    private static AbstractZookeeperClient abstractZookeeperClient;

    private static String ROOT = "/gate-way";

    private static String DELETE_ROOT = ROOT + "/delete";

    private static String UPDATE_ROOT = ROOT + "/update";

    private static String INSERT_ROOT = ROOT + "/insert";

    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,2,60, TimeUnit.SECONDS, new ArrayBlockingQueue(10));

    @Override
    public void afterPropertiesSet() throws Exception {
        abstractZookeeperClient = new CuratorZookeeperClient(zookeeperAddress, zkPort);
        boolean nodeExist = abstractZookeeperClient.existNode(ROOT);
        if (!nodeExist) {
            abstractZookeeperClient.createPersistentData(ROOT, "");
        }
        InsertNodeTask insertNodeTask = new InsertNodeTask((CuratorFramework) abstractZookeeperClient.getClient(), applicationEventPublisher, INSERT_ROOT);
        threadPoolExecutor.submit(insertNodeTask);
    }

    @Override
    public boolean insertOne(BlackListPO blackListPO) {
        boolean insertStatus = blackListMapper.insert(blackListPO) > 0;
        if (insertStatus) {
            this.syncDbToCache(blackListPO);
        }
        boolean existInsertNode = abstractZookeeperClient.existNode(INSERT_ROOT);
        if (existInsertNode) {
            abstractZookeeperClient.updateNodeData(INSERT_ROOT, String.valueOf(blackListPO.getId()));
        } else {
            abstractZookeeperClient.createTemporaryData(INSERT_ROOT, String.valueOf(blackListPO.getId()));
        }
        return true;
    }

    @Override
    public boolean deleteOne(BlackListPO blackListPO) {
        int deleteCount = blackListMapper.deleteById(blackListPO.getId());
        if (deleteCount > 0) {
            String originData = abstractZookeeperClient.getNodeData(ROOT + "/delete");
            if (originData == null) {
                abstractZookeeperClient.createTemporaryData(ROOT + "/delete", String.valueOf(blackListPO.getId()));
            }
        }
        return false;
    }

    @Override
    public boolean updateOne(BlackListPO blackListPO) {
        return false;
    }


    private boolean syncDbToCache(BlackListPO blackListPO) {
        int type = blackListPO.getType();
        String json = JSON.toJSONString(blackListPO);
        if (type == 0) {
//            redisService.lpush("memberId-black-list", json);
            iBlackListCache.setUserIdBlackMap(blackListPO.getIdentification(), blackListPO);
        } else if (type == 1) {
//            redisService.lpush("ip-black-list", json);
            iBlackListCache.setIpBlackMap(blackListPO.getIdentification(), blackListPO);
        } else if (type == 2) {
//            redisService.lpush("ua-black-list", json);
            iBlackListCache.setUaBlackMap(blackListPO.getIdentification(), blackListPO);
        }
        return true;
    }


}
